package main

import (
	"sync"
)

// Counter 一个包含互斥锁的计数器结构体
type Counter struct {
	mu    sync.Mutex
	count int
}

// foo 函数按值接收一个 Counter
// 错误：这会复制整个 Counter，包括内部的 mu
func foo1(c Counter) {
	c.mu.Lock() // 操作的是副本的锁
	c.count++
	c.mu.Unlock() // 释放的是副本的锁
}

func main1() {
	var c Counter

	// 调用 foo 函数，会发生值拷贝
	for i := 0; i < 1000; i++ {
		foo1(c)
	}

	// main 函数中的 c 和 foo 函数中的 c 是两个完全独立的实例
	// 对 foo 中副本的操作不会影响到 main 中的实例
	println(c.count) // 输出：0
}

// foo 函数接收一个 Counter 的指针
// 正确：所有操作都针对同一个 Counter 实例
func foo2(c *Counter) {
	c.mu.Lock() // 操作的是原始实例的锁
	c.count++
	c.mu.Unlock() // 释放的是原始实例的锁
}
func main2() {
	var c Counter

	// 调用 foo 函数，传递 c 的地址
	for i := 0; i < 1000; i++ {
		foo2(&c)
	}

	// main 函数中的 c 和 foo 函数中操作的 c 是同一个实例
	// foo 中的操作会正确地修改 main 中 c 的 count 值
	println(c.count) // 输出：1000
}

func main() {
	main1()
	main2()
}
